/*
 * Copyright (C) 2023, KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

#ifndef UKUI_SIDEBAR_NOTIFICATION_MODEL_H
#define UKUI_SIDEBAR_NOTIFICATION_MODEL_H

#include <QAbstractListModel>

#include <popup-notification.h>
#include <notification-close-reason.h>

#include "notification-utils.h"

namespace UkuiNotification {

class NotificationModel;
class NotificationModelPrivate;

class NotificationItem
{
    Q_GADGET
    friend class NotificationModel;
    friend class NotificationModelPrivate;
public:
    enum Flag {
        TransientPopup        = 0x01,     // 默认flag,自动消失弹窗
        ResidentPopup         = 0x02,     // 常驻弹窗
        Stored                = 0x04      // 已被存储
    };
    Q_ENUM(Flag)
//    Q_DECLARE_FLAGS(Flags, Flag)

    enum Property {
        Id = 0,
        Display,
        AppName,
        AppIconName,
        Icon,
        Summary,
        Body,
        Category,
        Image,
        CreateTime,
        Actions,
        ActionState,
        HasDefaultAction,
        EnableActionIcons,
        SoundFile,
        SuppressSound,
        Resident,
        Transient,
        Urgency,
        Timout,
        NoFold,
        PopupTimeout,
        /* 新属性 */
        IsStored,
        GroupIndex, // 23
        GroupName,
        GroupCount
    };
    Q_ENUM(Property)
//    Q_DECLARE_FLAGS(Propertys, Property)

    static QHash<int, QByteArray> roles();
    NotificationItem() = default;
    explicit NotificationItem(const PopupNotification& notification);

    uint id() const;
    int timeout() const;

private:
    void updateActions();
    void setData(const PopupNotification &notification);

    NotificationCloseReason::CloseReason closeReason {NotificationCloseReason::Expired};
    Flag flag {TransientPopup};
    QList<QVariant> actions;
    PopupNotification data;
};

class NotificationModel : public QAbstractListModel
{
    Q_OBJECT
public:
    static NotificationModel *instance();

    Q_DISABLE_COPY(NotificationModel)
    Q_DISABLE_MOVE(NotificationModel)

    int rowCount(const QModelIndex &parent) const override;
    QVariant data(const QModelIndex &index, int role) const override;
    QHash<int, QByteArray> roleNames() const override;

    Q_INVOKABLE void closeNotification(uint id);
    Q_INVOKABLE void execAction(uint id, int actionIndex = -1);

private Q_SLOTS:
    void onNotificationReceived(const UkuiNotification::PopupNotification &notification);
    void onNotificationClosed(uint id, UkuiNotification::NotificationCloseReason::CloseReason closeReason);
    void removeNotifications();

private:
    explicit NotificationModel(QObject *parent = nullptr);
    void init();

    // 查找消息在数组中的索引
    int findNotificationIndex(uint id) const;

    // 收起消息
    void storeNotification(uint id);

    // 通知数据更新
    void updateNotification(int row, const PopupNotification &notification);
    void updateNotificationTimer(uint id, int timeout, bool destroy);

private:
    NotificationModelPrivate *d { nullptr };
};

} // Notification

#endif //UKUI_SIDEBAR_NOTIFICATION_MODEL_H
